package com.m1.tzolkin.model.board;

import java.util.Collection;

import com.m1.tzolkin.model.TZResource;
import com.m1.tzolkin.model.buildables.IMonument;
import com.m1.tzolkin.model.buildables.IZonedBuilding;
import com.m1.tzolkin.model.players.ITZPlayer;
import com.m1.tzolkin.model.players.IWorker;
import com.m1.tzolkin.model.technos.ITechnology;
import com.m1.tzolkin.model.technos.Technologies;
import com.m1.tzolkin.model.temples.ITemple;
import com.m1.tzolkin.model.temples.TempleEnum;
import com.m1.tzolkin.model.wheels.WheelEnum;

public class PrintableBoard extends TZBoard implements IPrintableBoard {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2820208990422766900L;

	public PrintableBoard(Collection<ITZPlayer> players) {
		super(players);
		// TODO Auto-generated constructor stub
	}
	
	public String toString() {
		if (isWaitingForTurn() != 0) {
			return "En attente d'un ordre de tour (max = " + isWaitingForTurn() + ")\n";
		}
		final int frameSize = 70;
		class Centrer {
			String getFormattedStr(String s, int border) {
				return completeString(completeString(s, frameSize / 2 - border + s.length() / 2, true), frameSize - border * 2, false);
			}
			/**
			 * Retourne la chaine s avec suffisamment d'espaces au bout pour
			 *  arriver à un nombre de caractères égal à n.
			 * Si before, les espaces sont plac�s au d�but.
			 */
			String completeString(String s, int n, boolean before) {
				StringBuffer sb;
				if (before) {
					sb = new StringBuffer();
					for (int i = s.length(); i < n; ++i) {
						sb.append(" ");
					}
					sb.append(s);
				} else {
					sb = new StringBuffer(s);
					for (int i = s.length(); i < n; ++i) {
						sb.append(" ");
					}
				}
				return sb.toString();
			}
		}
		StringBuffer sb = new StringBuffer();
		Centrer c = new Centrer();
		// Date
		if (getCurrentPlayer() == getFirstPlayer() && getRemovedWorkers() == 0 && getPlacedWorkers() == 0) {
			for (int i = 0; i < frameSize; ++i) sb.append("="); sb.append("\n");
			String[] str = {
					"JOUR " + getTurnsCounter().getTurn() + "/" + DAYS,
					"tour " + (getActualTurn() + "/" + (getTurnsCounter().getTurns() * getPlayersManager().size()))
			};
			for (String s : str) {
				sb.append("|" + c.getFormattedStr(s, 1) + "|\n");
			}
			if (getTurnsCounter().feedingDay() != null) {
				sb.append("|" + c.getFormattedStr("~~ JOUR DE FESTIN ! ~~", 1) + "|\n");
			}
			for (int i = 0; i < frameSize; ++i) sb.append("="); sb.append("\n");
		}
		
		// Joueurs
		for (int i = 0; i < frameSize; ++i) sb.append("_"); sb.append("\n");
		StringBuffer buf;
		for (ITZPlayer pl : getPlayersManager()) {
			sb.append("|");
			buf = new StringBuffer(((getPlayersManager().getCurrent() == pl) ? "*" : " ") + ((getPlayersManager().getFirst() == pl) ? "#" : " "));
			buf.append(pl.getName() + " > M = " + c.completeString(pl.getCorn() + "", 2, true));
			for (TZResource r : TZResource.values()) {
				buf.append(" / " + r.name().charAt(0) + " = " + c.completeString(pl.getWallet().getResources(r) + "", 2, true));
			}
			buf.append(" / S = " + c.completeString(pl.getWallet().getSkulls() + "", 2, true));
			sb.append(c.completeString(buf.toString(), frameSize - 2, false));
			sb.append("|\n");
			// Ouvriers
			sb.append("|");
			buf = new StringBuffer("          En main : " + pl.getHandPawns().size()
					+ " / " + pl.getTotalPawns().size()
					+ " # score : " + (int) pl.getScore());
			sb.append(c.completeString(buf.toString(), frameSize - 2, false));
			sb.append("|\n");
		}
		
		sb.append("|"); for (int i = 0; i < frameSize - 2; ++i) sb.append("¨"); sb.append("|\n");
		
		// Premier Joueur / Calendrier
		buf = new StringBuffer();
		buf.append("  Case PJ : [");
		if (getFirstWorker() != null) buf.append(getFirstWorker().getOwner().getName());
		buf.append("]  |  Calendrier : ");
		for (int i = 0; i < getTurnsCounter().getCorn(); ++i) {
			buf.append("M");
		}
		sb.append("|" + c.completeString(buf.toString(), frameSize - 2, false) + "|\n");
		
		sb.append("|"); for (int i = 0; i < frameSize - 2; ++i) sb.append("¨"); sb.append("|\n");
		
		// Roues
		for (WheelEnum w : WheelEnum.values()) {
			buf = new StringBuffer(c.completeString(" " + w.name(), 13, false) + " : ");
			int i = 0;
			while (i < getWheel(w).getCircuitLength()) {
				if (i == 0) {
					buf.append("|");
				}
				IWorker worker = getWheel(w).getWorker(i);
				if (worker == null) {
					buf.append("__");
				} else if (getPlayersManager().contains(worker.getOwner())) {
					buf.append(worker.getOwner().getName().substring(0, 2));
				} else {
					buf.append("XX");
				}
				buf.append("|");
				++i;
			}
			while (i < getWheel(w).getFullLength()) {
				buf.append("//|");
				++i;
			}
			sb.append("|" + c.completeString(buf.toString(), frameSize - 2, false) + "|\n");
		}
		
		sb.append("|"); for (int i = 0; i < frameSize - 2; ++i) sb.append("¨"); sb.append("|\n");
		
		// Temples
		int maxLvl = 0;
		for (ITemple t : TempleEnum.values()) {
			maxLvl = Math.max(maxLvl, t.getHeight());
		}
		for (ITemple t : TempleEnum.values()) {
			buf = new StringBuffer("  " + c.completeString(t.getName(), 12, false) + " : |");
			for (int i = 0; i < t.getHeight() - 1; ++i) {
				for (ITZPlayer pl : getPlayersManager()) {
					if (getTemplePosition(t, pl) == i) {
						buf.append(pl.getName().substring(0, 2));
					} else {
						buf.append("__");
					}
				}
				buf.append("|");
			}
			String s = null;
			for (ITZPlayer pl : getPlayersManager()) {
				if (getTemplePosition(t, pl) == t.getHeight() - 1) {
					s = pl.getName().substring(0, 2);
				}
			}
			if (s == null) s = "__";
			buf.append(s + "|");
			sb.append("|" + c.completeString(buf.toString(), frameSize - 2, false) + "|\n");
		}
		
		sb.append("|"); for (int i = 0; i < frameSize - 2; ++i) sb.append("¨"); sb.append("|\n");
		
		// Technologies
		
		maxLvl = 0;
		for (ITechnology t : Technologies.values()) {
			maxLvl = Math.max(maxLvl, t.getHeight());
		}
		for (ITechnology t : Technologies.values()) {
			buf = new StringBuffer("  " + c.completeString(t.getName(), 20, false) + " : ");
			for (int i = 0; i < t.getHeight(); ++i) {
				for (ITZPlayer pl : getPlayersManager()) {
					if (getTechnologyManager().getPosition(t, pl) == i) {
						buf.append(pl.getName().substring(0, 2));
					} else {
						buf.append("__");
					}
				}
				buf.append("|");
			}
			buf.append("_|");
			sb.append("|" + c.completeString(buf.toString(), frameSize - 2, false) + "|\n");
		}
		
		sb.append("|"); for (int i = 0; i < frameSize - 2; ++i) sb.append("¨"); sb.append("|\n");
		
		// B�timents achetables
		
		sb.append("| Bâtiments : ");
		for (IZonedBuilding b : getBuildings()) {
			sb.append(b.getName() + ", ");
		}
		sb.append("\n");
		sb.append("| Monuments : ");
		for (IMonument b : getMonuments()) {
			sb.append(b.getName() + ", ");
		}
		sb.append("\n");
		
		
		sb.append("|"); for (int i = 0; i < frameSize - 2; ++i) sb.append("_"); sb.append("|\n");

		return sb.toString();
	}

}
